`include "define.svh"

module exc_ctrl(
    input wire [`PC_WIDTH - 1 : 0]      exc_pc,
    input wire [`EXCCODE_WIDTH - 1 : 0] exc_code,
    input wire                          exc_pc_in_delay_slot,
    input wire [`PC_WIDTH - 1 : 0]      badvaddr,
    
    input wire                          status_exl_i,
    input wire [31 : 0]                 epc_i,
    
    output reg                          pipeline_flush,
    output reg                          is_exc,
    output reg                          is_eret,
    output reg                          is_Adexc,
    output reg [31 : 0]                 pc_in_epc,
    
    output reg [31 : 0]                 epc_wdata,
    output reg                          cause_bd_wdata,
    output reg                          status_exl_wdata,
    output reg [31 : 0]                 badvaddr_wdata,
    output reg [4 : 0]                  cause_excode_wdata

);

    always_comb begin
        is_exc = ~(exc_code == `Exc_None || exc_code == `Exc_ERET) & (~status_exl_i);
        is_eret = (exc_code == `Exc_ERET);
        is_Adexc = (exc_code == `Exc_AdEL || exc_code == `Exc_AdES);
        pc_in_epc = epc_i;
    end
    
    always_comb pipeline_flush = (is_exc | is_eret);
    
    always_comb epc_wdata = exc_pc_in_delay_slot ? exc_pc - 4 : exc_pc;
    always_comb cause_bd_wdata = exc_pc_in_delay_slot;
    always_comb status_exl_wdata = is_exc;
    always_comb badvaddr_wdata = badvaddr;
    always_comb cause_excode_wdata = exc_code;
    
endmodule
